package org.xdq.生产者消费者问题;

public class Test {
    //面包柜
    static class Guizi{

        private int size;//面包数量
        private int cap;//容量

        Guizi(int cap){
            this.cap = cap;
        }

        boolean isFull(){
            return size == cap;
        }

        boolean isEmpty(){
            return size == 0;
        }

        void add(){
            synchronized (this) {
                while(this.isFull()){
                    // wait方法是Object的方法，只能 （1）通过锁对象，（2）在同步代码块中 调用
                    try {
                        System.out.println(Thread.currentThread().getName()+"：满了，等待中...");
                        this.wait();//此时，当前线程在锁对象下等待，直到其它线程通过该锁对象唤醒之
                        System.out.println(Thread.currentThread().getName()+"：被唤醒！");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                size++;
                System.out.println(Thread.currentThread().getName()+"：放入一个面包，面包数为"+size);
                this.notifyAll();//该方法是Object的方法，只能 （1）通过锁对象，（2）在同步代码块中 调用
                Thread.yield();
            }
        }

        void remove(){
            synchronized (this) {
                while(this.isEmpty()){
                    try {
                        System.out.println(Thread.currentThread().getName()+"：空了，等待中...");
                        this.wait();
                        System.out.println(Thread.currentThread().getName()+"：被唤醒！");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                size--;
                System.out.println(Thread.currentThread().getName()+"：取出一个面包，面包数为"+size);
                this.notifyAll();
                Thread.yield();
            }
        }
    }

    public static void main(String[] args) {

        Guizi guizi = new Guizi(5);//共享数据区
        for(int k=1;k<=5;k++){
            new Thread(()->{
                for(int i=0;i<100;i++){
                    guizi.add();
                }
            },"面包师父"+k).start();

            new Thread(()->{
                for(int i=0;i<100;i++){
                    guizi.remove();
                }
            },"店员"+k).start();
        }


    }
}
